package com.rm.freedrawsample.slice;

import com.rm.freedrawsample.*;
import com.rm.freedrawsample.ResourceTable;
import com.rm.freedrawview.*;

import ohos.aafwk.ability.AbilitySlice;
import ohos.aafwk.content.Intent;
import ohos.agp.colors.RgbColor;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.media.image.PixelMap;
import ohos.utils.PacMap;

import static ohos.agp.components.element.ShapeElement.OVAL;

/**
 * AbilityDrawSlice.
 *
 * @author author
 * @version version
 */
public class AbilityDrawSlice extends AbilitySlice implements Component.ClickedListener,
        Slider.ValueChangedListener, FreeDrawView.DrawCreatorListener,
        PathDrawnListener, PathRedoUndoCountChangeListener, AbilityStateCall {
    private static final int THICKNESS_STEP = 2;
    private static final int THICKNESS_MAX = 80;
    private static final int THICKNESS_MIN = 15;
    private static final int ALPHA_STEP = 1;
    private static final int ALPHA_MAX = 255;
    private static final int ALPHA_MIN = 0;
    private FreeDrawView mFreeDrawView;
    private Image mIconBack;
    private Component mSideView;
    private Button mBtnRandomColor;
    private Button mBtnUndo;
    private Button mBtnRedo;
    private Button mBtnClearAll;
    private Slider mThicknessBar;
    private Slider mAlphaBar;
    private Text mTxtRedoCount;
    private Text mTxtUndoCount;
    private ProgressBar mProgressBar;
    private Image mImgScreen;

    @Override
    public void onStart(Intent intent) {
        super.onStart(intent);
        super.setUIContent(ResourceTable.Layout_ability_draw);

        getWindow().setStatusBarColor(getColor(ResourceTable.Color_colorPrimaryDark));
        ((AbilityDraw) getAbility()).setAbilityCall(this);
        finView();
        initData();

        mAlphaBar.setMaxValue((ALPHA_MAX - ALPHA_MIN) / ALPHA_STEP);
        int alphaProgress = ((mFreeDrawView.getPaintAlpha() - ALPHA_MIN) / ALPHA_STEP);
        mAlphaBar.setProgressValue(alphaProgress);
        mAlphaBar.setValueChangedListener(this);
        mAlphaBar.setProgressColor(new Color(getColor(ResourceTable.Color_colorAccent)));
        setThumbElement(mAlphaBar);
        setProgressBackgroundElement(mAlphaBar);

        mThicknessBar.setMaxValue((THICKNESS_MAX - THICKNESS_MIN) / THICKNESS_STEP);
        int thicknessProgress = (int)
                (((double) mFreeDrawView.getPaintWidth() - THICKNESS_MIN) / THICKNESS_STEP);
        mThicknessBar.setProgressValue(thicknessProgress);
        mThicknessBar.setProgressColor(new Color(getColor(ResourceTable.Color_colorAccent)));
        setThumbElement(mThicknessBar);
        setProgressBackgroundElement(mThicknessBar);
        mThicknessBar.setValueChangedListener(this);
        setBackgroundColor(mSideView, mFreeDrawView.getPaintColor());
    }

    private void finView() {
        mImgScreen = (Image) findComponentById(ResourceTable.Id_img_screen);
        mIconBack = (Image) findComponentById(ResourceTable.Id_icon_back);
        mIconBack.setClickedListener(this);
        mTxtRedoCount = (Text) findComponentById(ResourceTable.Id_txt_redo_count);
        mTxtUndoCount = (Text) findComponentById(ResourceTable.Id_txt_undo_count);

        mProgressBar = (ProgressBar) findComponentById(ResourceTable.Id_progress);

        mFreeDrawView = (FreeDrawView) findComponentById(ResourceTable.Id_free_draw_view);
        mFreeDrawView.setOnPathDrawnListener(this);
        mFreeDrawView.setPathRedoUndoCountChangeListener(this);

        mSideView = findComponentById(ResourceTable.Id_side_view);
        mBtnRandomColor = (Button) findComponentById(ResourceTable.Id_btn_color);
        mBtnUndo = (Button) findComponentById(ResourceTable.Id_btn_undo);
        mBtnRedo = (Button) findComponentById(ResourceTable.Id_btn_redo);
        mBtnClearAll = (Button) findComponentById(ResourceTable.Id_btn_clear_all);
        mAlphaBar = (Slider) findComponentById(ResourceTable.Id_slider_alpha);
        mThicknessBar = (Slider) findComponentById(ResourceTable.Id_slider_thickness);
        mBtnRandomColor.setClickedListener(this);
        mBtnUndo.setClickedListener(this);
        mBtnRedo.setClickedListener(this);
        mBtnClearAll.setClickedListener(this);
        findComponentById(ResourceTable.Id_ic_github).setClickedListener(this);
        findComponentById(ResourceTable.Id_ic_delete).setClickedListener(this);
        findComponentById(ResourceTable.Id_ic_screenshot).setClickedListener(this);
    }

    private void initData() {
        if (AbilityDrawUtils.isGoToAbilityDraw()) {
            AbilityDrawUtils.setGoToAbilityDraw(false);
            showLoadingSpinner();
            FileHelper.getSavedStoreFromFile(this,
                    new FileHelper.StateExtractorInterface() {
                        @Override
                        public void onStateExtracted(FreeDrawSerializableState state) {
                            if (state != null) {
                                mFreeDrawView.restoreStateFromSerializable(state);
                                setBackgroundColor(mSideView, mFreeDrawView.getPaintColor());
                            }
                            hideLoadingSpinner();
                        }

                        @Override
                        public void onStateExtractionError() {
                            hideLoadingSpinner();
                        }
                    });
        }
    }


    private void showLoadingSpinner() {

        mProgressBar.setVisibility(Component.VISIBLE);
    }

    private void hideLoadingSpinner() {

        mProgressBar.setVisibility(Component.HIDE);
    }

    private void setThumbElement(Slider slider) {
        ShapeElement shapeElement = new ShapeElement();
        Color color = new Color(getColor(ResourceTable.Color_colorAccent));
        shapeElement.setRgbColor(RgbColor.fromArgbInt(color.getValue()));
        shapeElement.setShape(OVAL);
        shapeElement.setBounds(0, 0, (int) SystemUtils.vp2px(this, 12), (int) SystemUtils.vp2px(this, 12));
        slider.setThumbElement(shapeElement);
    }

    private void setProgressBackgroundElement(Slider slider) {
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(new RgbColor(0xff, 0xff, 0xff, 0x33));
        shapeElement.setCornerRadius(10);
        slider.setProgressBackgroundElement(shapeElement);
    }


    private void setBackgroundColor(Component component, int argb) {
        ShapeElement shapeElement = new ShapeElement();
        shapeElement.setRgbColor(RgbColor.fromArgbInt(argb));
        component.setBackground(shapeElement);
    }

    private void changeColor() {
        int color = ColorHelper.getRandomMaterialColor(this);
        mFreeDrawView.setPaintColor(color);
        setBackgroundColor(mSideView, mFreeDrawView.getPaintColor());
    }

    private void takeAndShowScreenshot() {
        mIconBack.setVisibility(Component.VISIBLE);
        mFreeDrawView.getDrawScreenshot(this);
    }

    @Override
    protected void onInactive() {
        super.onInactive();
        FileHelper.saveStateIntoFile(this, mFreeDrawView.getCurrentViewStateAsSerializable(), null);
    }


    @Override
    public void onSaveAbilityState(PacMap outState) {
        mFreeDrawView.onSaveAbilityState(outState);
    }

    @Override
    public void onRestoreAbilityState(PacMap inState) {
        setBackgroundColor(mSideView, mFreeDrawView.getPaintColor());
        mFreeDrawView.onRestoreAbilityState(inState);
    }


    @Override
    public void onClick(Component component) {
        int id = component.getId();
        if (id == mBtnRandomColor.getId()) {
            changeColor();
        } else if (id == mBtnUndo.getId()) {
            mFreeDrawView.undoLast();
        } else if (id == mBtnRedo.getId()) {
            mFreeDrawView.redoLast();
        } else if (id == mBtnClearAll.getId()) {
            mFreeDrawView.undoAll();
        } else if (id == ResourceTable.Id_ic_github) {
            String string = getString(ResourceTable.String_github_url);
            IntentHelper.openUrl(this, string);
        } else if (id == ResourceTable.Id_ic_delete) {
            mFreeDrawView.clearDrawAndHistory();
            FileHelper.deleteSavedStateFile(this);
        } else if (id == ResourceTable.Id_ic_screenshot) {
            takeAndShowScreenshot();
        } else if (id == ResourceTable.Id_icon_back) {
            getAbility().terminateAbility();
        }
    }

    @Override
    public void onProgressUpdated(Slider slider, int progress, boolean b1) {
        if (slider.getId() == mThicknessBar.getId()) {
            mFreeDrawView.setPaintWidthPx(THICKNESS_MIN + (progress * THICKNESS_STEP));
        } else {
            mFreeDrawView.setPaintAlpha(ALPHA_MIN + (progress * ALPHA_STEP));
        }
    }

    @Override
    public void onTouchStart(Slider slider) {

    }

    @Override
    public void onTouchEnd(Slider slider) {

    }

    @Override
    protected void onBackPressed() {
        if (mImgScreen.getVisibility() == Component.VISIBLE) {
            findComponentById(ResourceTable.Id_ic_screenshot).setVisibility(Component.VISIBLE);
            findComponentById(ResourceTable.Id_ic_delete).setVisibility(Component.VISIBLE);
            mImgScreen.setPixelMap(null);
            mImgScreen.setVisibility(Component.HIDE);
            mFreeDrawView.setVisibility(Component.VISIBLE);
            mSideView.setVisibility(Component.VISIBLE);
            mIconBack.setVisibility(Component.HIDE);
        } else {
            super.onBackPressed();
        }

    }

    @Override
    public void onPathStart() {

    }

    @Override
    public void onNewPathDrawn() {

    }

    @Override
    public void onUndoCountChanged(int undoCount) {
        mTxtUndoCount.setText(String.valueOf(undoCount));
    }

    @Override
    public void onRedoCountChanged(int redoCount) {
        mTxtRedoCount.setText(String.valueOf(redoCount));
    }

    @Override
    public void onDrawCreated(PixelMap draw) {
        mSideView.setVisibility(Component.HIDE);
        mFreeDrawView.setVisibility(Component.HIDE);
        findComponentById(ResourceTable.Id_ic_screenshot).setVisibility(Component.HIDE);
        findComponentById(ResourceTable.Id_ic_delete).setVisibility(Component.HIDE);
        mImgScreen.setVisibility(Component.VISIBLE);
        mImgScreen.setPixelMap(draw);
    }

    @Override
    public void onDrawCreationError() {
        Toast.showShort(this, "Error, cannot create bitmap");
    }


}
